﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using FRL.DebtChased.Repository;
using FRL.DebtChased.Silverlight.Library;
using FRL.DebtChased.Silverlight.Library.RichContentService;

namespace FRL.DebtChased.CommBodyEditor
{

	/// <summary>
	/// Declaration of MainPage class
	/// </summary>
	public partial class MainPage : UserControl,IDebtChasedMainPlugInWindow
	{

		/////////////////////////////////////////////////////////////
		// Constants

		private const string Action_PickAction = "[Pick Action]";

		private const string Action_Edit = "Edit";

		private const string Action_Clone = "Clone";

		private const string Action_Delete = "Delete";

		/////////////////////////////////////////////////////////////
		// Attributes

		private static MainPage m_singleton = null;
		public static MainPage Singleton
		{
			get { return m_singleton; }
		}

		private bool m_bBlockEvents = true;

		/////////////////////////////////////////////////////////////
		// Construction

		public MainPage()
		{

			// Initialize member variables
			m_singleton = this;

			// Load xaml resources
			InitializeComponent();

			// Initialize library
			new LibrarySession(this);

			// Do the initial load of data
			_loadSupportingData();

			// Set up animations
			AnimFadeOutEditor.Completed += new EventHandler(AnimFadeOutEditor_Completed);

			// Update flag
			m_bBlockEvents = false;

			// Setup controls
			_setupControls();

		}

		/////////////////////////////////////////////////////////////
		// Implementation of IDebtChasedMainPlugInWindow

		public void ShowHourglass(bool bTrue)
		{

			// Show/hide hourglass
			hourglassCtrl.IncShowCount(bTrue);

		}

		public void WebsiteMenuClicked(DebtChasedWebsiteMenuCtrl.eMenuItem menuItemId)
		{
			throw new NotImplementedException();
		}

		public void ContactPointButtonClick(PointActiveButton button, int iContactId, Guid contactPointId)
		{
			throw new NotImplementedException();
		}

		/////////////////////////////////////////////////////////////
		// Event Handlers

		void cboActions_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// shortcuts
			if (m_bBlockEvents)
				return;

			// Get the action combo
			ComboBox cboActions = sender as ComboBox;

			// Get the row-index
			int iRowIndex = Grid.GetRow(cboActions);

			// Get the object from the type control
			TextRectangleCtrl trType = gridCommBody.FindCellContent(
				0, 
				iRowIndex, 
				typeof(TextRectangleCtrl)
			) as TextRectangleCtrl;
			CommBodySummaryTransport cbst = trType.Tag as CommBodySummaryTransport;

			// Compare actions
			if (cboActions.SelectedItem.ToString() == Action_Edit)
			{

				// Edit the comm-body
				_loadCommBodyAndEdit(cbst.CommBodyId);

			}
			else if (cboActions.SelectedItem.ToString() == Action_Clone)
			{

				// Call server function
				MessageBoxes.PopupDevMessage();

			}
			else if (cboActions.SelectedItem.ToString() == Action_Delete)
			{

				// Option to delete
				if(MessageBoxes.PopupOption(string.Format("Delete comm body \"{0}\"?",cbst.Name)))
				{

					// Call server function
					MessageBoxes.PopupDevMessage();

				}

			}

			// Reset the action
			cboActions.SelectedIndex = 0;			

		}

		private void butRefresh_Click(object sender, RoutedEventArgs e)
		{

			// Reload the list
			_refreshList();

		}

		private void butNewLetter_Click(object sender, RoutedEventArgs e)
		{

			// Call sibling function
			_newCommBody( Definitions.eCommBodyType.Letter );

		}

		private void butNewEmail_Click(object sender, RoutedEventArgs e)
		{

			// Call sibling function
			_newCommBody( Definitions.eCommBodyType.Email );

		}

		private void butNewSMS_Click(object sender, RoutedEventArgs e)
		{

			// Call sibling function
			_newCommBody( Definitions.eCommBodyType.SMS );

		}

		/////////////////////////////////////////////////////////////
		// Operations

		private void _setupControls()
		{

			// Enable/disable buttons

		}

		private void _newCommBody(Definitions.eCommBodyType commBodyType)
		{

			// Setup editor
			CommBodyTransport cbt = new CommBodyTransport() { 
				CommBodyId = 0,
				CommBodyType = (int)commBodyType,
				CommTemplateId = 0
			};
			ctrlEditor.Set(cbt);

			// Show editing panel
			FadeInEditor(true);

		}

		private void _addRow()
		{

			// Create a new row
			RowDefinition row = new RowDefinition();
			gridCommBody.RowDefinitions.Add(row);

			// Calculate new row index
			int iRowIndex = gridCommBody.RowDefinitions.Count - 1;

			// Set controls
			TextRectangleCtrl trType = new TextRectangleCtrl();
			trType.Style = this.Resources["CellValueStyle"] as Style;
			gridCommBody.Children.Add(trType);
			Grid.SetColumn(trType, 0);
			Grid.SetRow(trType, iRowIndex);

			TextRectangleCtrl trName = new TextRectangleCtrl();
			trName.Style = this.Resources["CellValueStyle"] as Style;
			gridCommBody.Children.Add(trName);
			Grid.SetColumn(trName, 1);
			Grid.SetRow(trName, iRowIndex);

			TextRectangleCtrl trInUse = new TextRectangleCtrl();
			trInUse.Style = this.Resources["CellValueStyle"] as Style;
			gridCommBody.Children.Add(trInUse);
			Grid.SetColumn(trInUse, 2);
			Grid.SetRow(trInUse, iRowIndex);

			ComboBox cboActions = new ComboBox();
			cboActions.SelectionChanged += new SelectionChangedEventHandler(cboActions_SelectionChanged);
			//cboActions.Style = this.Resources["FatBlueComboBoxStyle"] as Style;
			gridCommBody.Children.Add(cboActions);
			Grid.SetColumn(cboActions, 3);
			Grid.SetRow(cboActions, iRowIndex);

		}

		private void _removeRow()
		{

			// Remove the bottom row and controls
			gridCommBody.DeleteRows(gridCommBody.RowDefinitions.Count - 1, 1);

		}

		private void _getControlsAtRowIndex(
			int iRowIndex, 
			out TextRectangleCtrl trType, 
			out TextRectangleCtrl trName,
			out TextRectangleCtrl trInUse,
			out ComboBox cboAction
		)
		{

			// Reset function parameters
			trType = null;
			trName = null;
			trInUse = null;
			cboAction = null;

			// Loop through controls
			foreach (FrameworkElement el in gridCommBody.Children)
			{

				// Check row index
				if (Grid.GetRow(el) == iRowIndex)
				{

					// Compare column indexes
					int iColumn = Grid.GetColumn(el);
					if (iColumn == 0)
					{
#if DEBUG
						Debug.Assert(trType == null);
#endif // #if DEBUG
						trType = el as TextRectangleCtrl;
#if DEBUG
						Debug.Assert(trType != null);
#endif // #if DEBUG
					}
					else if (iColumn == 1)
					{
#if DEBUG
						Debug.Assert(trName == null);
#endif // #if DEBUG
						trName = el as TextRectangleCtrl;
#if DEBUG
						Debug.Assert(trName != null);
#endif // #if DEBUG
					}
					else if (iColumn == 2)
					{
#if DEBUG
						Debug.Assert(trInUse == null);
#endif // #if DEBUG
						trInUse = el as TextRectangleCtrl;
#if DEBUG
						Debug.Assert(trInUse != null);
#endif // #if DEBUG
					}
					else if (iColumn == 3)
					{
#if DEBUG
						Debug.Assert(cboAction == null);
#endif // #if DEBUG
						cboAction = el as ComboBox;
#if DEBUG
						Debug.Assert(cboAction != null);
#endif // #if DEBUG
					}
#if DEBUG
					else
						Debug.Assert(false);
#endif // #if DEBUG

				}

			}

			// Check function parameters
#if DEBUG
			Debug.Assert(trType != null);
			Debug.Assert(trName != null);
			Debug.Assert(trInUse != null);
			Debug.Assert(cboAction != null);
#endif // #if DEBUG

		}

		public void FadeInEditor(bool bFadeIn)
		{

			// If fading in...
			if (bFadeIn)
			{

				// Ensure controls are visible
				ctrlEditor.Opacity = 0;
				blankingCanvas.Opacity = 0;
				ctrlEditor.Visibility = System.Windows.Visibility.Visible;
				blankingCanvas.Visibility = System.Windows.Visibility.Visible;

				// Start the animation
				AnimFadeInEditor.Begin();

			}
			else
			{

				// Start the animation
				AnimFadeOutEditor.Begin();

			}

		}

		public void CloseCommBodyCtrl( bool bContentSaved )
		{

			// Fade out the editor
			MainPage.Singleton.FadeInEditor(false);

			// Update list
			if (bContentSaved)
				_refreshList();
				
		}

		void AnimFadeOutEditor_Completed(object sender, EventArgs e)
		{

			// Hide the canvas and controls
			blankingCanvas.Visibility = System.Windows.Visibility.Collapsed;
			ctrlEditor.Visibility = System.Windows.Visibility.Collapsed;

		}

		/////////////////////////////////////////////////////////////
		#region Rich content service operations

		private void _loadSupportingData()
		{
#if DEBUG
			Debug.Assert(CachedData.Singleton.CommTemplateList == null);
#endif // #if DEBUG

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Load real or fake supporting data
#if USEFAKEDATA

			// Create event
			object[] results = new object[1];
			results[0] = CachedData.GetDummySupportingData();
			GetClientEditorSupportDataCompletedEventArgs e = new GetClientEditorSupportDataCompletedEventArgs(
				results,
				null,
				false,
				null
			);

			// Call completed event
			proxy_GetClientEditorSupportDataCompleted(null, e);

#else

			// Start by downloading the supporting data
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.GetCommBodyEditorSupportDataCompleted += new EventHandler<GetCommBodyEditorSupportDataCompletedEventArgs>(proxy_GetCommBodyEditorSupportDataCompleted);
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetCommBodyEditorSupportDataAsync();

#endif // #if USEFAKEDATA

		}

		void proxy_GetCommBodyEditorSupportDataCompleted(object sender, GetCommBodyEditorSupportDataCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage("Failed to load supporting data from server.");
			else
			{

				// Update the cached data
				CachedData.Singleton.AddIncoming(e.Result);

				// Update controls
				ctrlEditor.SupportingDataLoaded();

				// Load the list
				_refreshList();

			}

			// Setup controls
			_setupControls();

		}

		private void _refreshList()
		{

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Load real or fake list of comm bodies
#if USEFAKEDATA

			// Create event
			object[] results = new object[1];
			results[0] = CachedData.GetDummySupportingData();
			GetClientEditorSupportDataCompletedEventArgs e = new GetClientEditorSupportDataCompletedEventArgs(
				results,
				null,
				false,
				null
			);

			// Call completed event
			proxy_GetClientEditorSupportDataCompleted(null, e);

#else

			// Load the comm-body summary list
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.GetCommBodyListCompleted += new EventHandler<GetCommBodyListCompletedEventArgs>(proxy_GetCommBodyListCompleted);
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetCommBodyListAsync();

#endif // #if USEFAKEDATA

		}

		void proxy_GetCommBodyListCompleted(object sender, GetCommBodyListCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage_InternalError("Failed to load comm-body list from server.");
			else
			{

				// Block events
				m_bBlockEvents = true;
				{

					// Reload the list
					int iRowsRequired = e.Result.Count() + 1;
					while (gridCommBody.RowDefinitions.Count < iRowsRequired)
						_addRow();
					while (gridCommBody.RowDefinitions.Count > iRowsRequired)
						_removeRow();

					// Populate rows
					for (int i1 = 0; i1 < e.Result.Count; i1++)
					{

						// Get the next comm-body object
						CommBodySummaryTransport cb = e.Result[i1];

						// Get the controls
						TextRectangleCtrl trType;
						TextRectangleCtrl trName;
						TextRectangleCtrl trInUse;
						ComboBox cboActions;
						_getControlsAtRowIndex(i1 + 1, out trType, out trName, out trInUse, out cboActions);
						trType.Text = ((Definitions.eCommBodyType)cb.CommBodyType).ToString();
						trType.Tag = cb;
						trName.Text = cb.Name;
						if (cb.UsageCount == 0)
							trInUse.Text = "No";
						else
							trInUse.Text = string.Format("Yes [{0}]", cb.UsageCount);

						// Load actions
						cboActions.Items.Clear();
						cboActions.Items.Add(Action_PickAction);
						cboActions.Items.Add(Action_Edit);
						cboActions.Items.Add(Action_Clone);
						if (cb.UsageCount == 0)
							cboActions.Items.Add(Action_Delete);
						cboActions.SelectedIndex = 0;

					}

				}
				m_bBlockEvents = false;

			}

			// Setup controls
			_setupControls();

		}

		private void _loadCommBodyAndEdit(int iCommBodyId)
		{

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Load real or fake list of comm bodies
#if USEFAKEDATA

			// Create event
			object[] results = new object[1];
			results[0] = CachedData.GetDummySupportingData();
			GetClientEditorSupportDataCompletedEventArgs e = new GetClientEditorSupportDataCompletedEventArgs(
				results,
				null,
				false,
				null
			);

			// Call completed event
			proxy_GetClientEditorSupportDataCompleted(null, e);

#else

			// Load the comm-body summary list
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.GetCommBodyCompleted += new EventHandler<GetCommBodyCompletedEventArgs>(proxy_GetCommBodyCompleted);
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetCommBodyAsync(iCommBodyId);

#endif // #if USEFAKEDATA

		}

		void proxy_GetCommBodyCompleted(object sender, GetCommBodyCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage_InternalError("Failed to load comm body from server.");
			else
			{

				// Setup editor
				CommBodyTransport cbt = e.Result as CommBodyTransport;
				ctrlEditor.Set(cbt);

				// Show editing panel
				FadeInEditor(true);

			}

			// Setup controls
			_setupControls();

		}

		#endregion Rich content service operations

	}

}
